#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/configfs.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/device.h>

struct pinctrl_state * state1;
struct pinctrl_state * state2;
struct pinctrl * gpio_pinctrl;

ssize_t selectmux_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    unsigned long select;
    select = simple_strtoul(buf, NULL, 10);
    if (select == 1) {
        pinctrl_select_state(gpio_pinctrl, state1);     // 选择功能1状态
    } else if (select == 2) {
        pinctrl_select_state(gpio_pinctrl, state2);     // 选择功能2状态
    }
    return count;
}

DEVICE_ATTR_WO(selectmux);

int pinctrl_get_and_lookstate (struct device * dev){
    
    gpio_pinctrl = pinctrl_get(dev);
    if(IS_ERR(gpio_pinctrl)){
        printk("pinctrl get fail\n");
        return -1;
    }
    state1 = pinctrl_lookup_state(gpio_pinctrl,"mygpio_func1");
    if(IS_ERR(state1)){
        printk("pinctrl lookup state fail\n");
        return -1;
    }
    state2 = pinctrl_lookup_state(gpio_pinctrl,"mygpio_func2");
    if(IS_ERR(state2)){
        printk("pinctr2 lookup state fail\n");
        return -1;
    }
    return 0;
}

static int my_platform_probe(struct platform_device * dev){
    printk("platform driver probe\n");
    pinctrl_get_and_lookstate(&dev->dev);
    device_create_file(&dev->dev,&dev_attr_selectmux);
    return 0;
}

const struct of_device_id my_platform_match_table[]={
    {.compatible = "mygpio",},
};


int my_platform_remove(struct platform_device * dev){
    printk(KERN_INFO "my_platform_remove: Removing platform device\n");
    device_del(&dev->dev);
    return 0;
}

static struct platform_driver my_platform_driver ={
    .probe = my_platform_probe,
    .remove = my_platform_remove,
    .driver = {
        .name = "my_platform_device",
        .owner = THIS_MODULE,
        .of_match_table = my_platform_match_table,
    },
 };
 

static int __init myplaform_init(void){
    int ret;
    ret = platform_driver_register(&my_platform_driver);
    if(ret){
        printk("platform driver register fail\n");
        return -1;
    }
    return 0;
}

static void __exit myplaform_exit(void){
    platform_driver_unregister(&my_platform_driver);
}

MODULE_AUTHOR("WLZ");
MODULE_LICENSE("GPL");
module_init(myplaform_init);
module_exit(myplaform_exit);